﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;

namespace BitTorrentSharp.Client
{
	using Peers;


	/// <summary>
	/// Represent as a peer that the client could visit.
	/// </summary>
	public class PeerFriend
	{
		#region Internal Information

		/// <summary>
		/// Get the information of the friend peer.
		/// </summary>
		public Peer PeerInfo
		{
			get;
			private set;
		}

		#endregion

		#region State Information

		/// <summary>
		/// Get a value that indicates if the friend is chocked.
		/// </summary>
		public bool IsChocked
		{
			get;
			private set;
		}

		/// <summary>
		/// Get a value that indicates if the friend is interested.
		/// </summary>
		public bool IsInterested
		{
			get;
			private set;
		}

		/// <summary>
		/// Get a value that indicates if the friend has been connected.
		/// </summary>
		public bool IsConnected
		{
			get;
			private set;
		}

		#endregion

		#region Actions

		/// <summary>
		/// Try to connect to the target peer.
		/// </summary>
		public void Connect()
		{
		}

		/// <summary>
		/// Check if there's any new message comes.
		/// </summary>
		/// <remarks>
		/// Call this method periodly in your main timer/loop.
		/// </remarks>
		public void CheckMessage()
		{
			this.CheckMessageCore();
		}

		#region Internal Methods

		/// <summary>
		/// Check if there's any new message comes. This is the internal implementation.
		/// </summary>
		protected virtual void CheckMessageCore()
		{
		}

		#endregion

		#endregion

		#region Events

		/// <summary>
		/// Raises when a new message is received from this friend.
		/// </summary>
		public event EventHandler<MessageEventArgs> MessageReceived;

		/// <summary>
		/// Raises when the friend sends a choke notification.
		/// </summary>
		public event EventHandler Choke;
		/// <summary>
		/// Raises when the friend sends a unchoke notification.
		/// </summary>
		public event EventHandler Unchoke;

		/// <summary>
		/// Raises when the friend send a interested notification.
		/// </summary>
		public event EventHandler Interested;

		/// <summary>
		/// Raises when the friend send a unintrresetd notification.
		/// </summary>
		public event EventHandler Uninterested;

		/// <summary>
		/// Raises when the friend has been connected.
		/// </summary>
		public event EventHandler Connected;

		/// <summary>
		/// Raises when the friend has been disconnected.
		/// </summary>
		public event EventHandler Disconnected;

		#endregion

		#region Low-level TCP Operations

		#region TCP Client

		/// <summary>
		/// The tcp client for this peer.
		/// </summary>
		private TcpClient _client;

		#endregion

		#region Actions

		/// <summary>
		/// Initialize the TCP client.
		/// </summary>
		private void InitializeTcpClient()
		{
			// Create connection using any port.
			// TODO: using fixed port.
			this._client = new TcpClient(new IPEndPoint(IPAddress.Any, 0));
		}

		/// <summary>
		/// Connect to the target TCP end-point.
		/// </summary>
		private void ConnectTcpClient()
		{
			var endPoint = this.PeerEndPoint;
			this._client.Connect(endPoint);
		}

		#endregion

		#region Helper Functions

		/// <summary>
		/// Get the IP end-point from peer information.
		/// </summary>
		private IPEndPoint PeerEndPoint
		{
			get
			{
				return new IPEndPoint(IPAddress.Parse(this.PeerInfo.IP), this.PeerInfo.Port);
			}
		}

		#endregion

		#endregion
	}
}
